﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;

//TODO: one day, support one-to-one relationships

namespace Close2Poco
{
    /// <summary>
    /// Represents a relationship between two classes
    /// </summary>
    public class Relationship
    {
        public Relationship(PropertyInfo listEnd, PropertyInfo refEnd, IList<PropertyInfo> keyAtListEnd, IList<PropertyInfo> keyAtRefEnd)
        {
            
            ListEnd = listEnd;
            RefEnd  = refEnd;

            KeyAtListEnd = keyAtListEnd == null ? null : new ReadOnlyCollection<PropertyInfo>(keyAtListEnd);
            KeyAtRefEnd  = new ReadOnlyCollection<PropertyInfo>(keyAtRefEnd);

            if(keyAtListEnd != null)
                CheckKeysMatch();
        }

        void CheckKeysMatch()
        {
            if (KeyAtListEnd.Count != KeyAtRefEnd.Count)
                throw new ArgumentException("Keys must contain same number of properties");
            for(int i = 0; i < KeyAtListEnd.Count; i++)
                if(!KeyAtRefEnd[i].PropertyType.IsAssignableFrom(KeyAtListEnd[i].PropertyType))
                    throw new ArgumentException("Key's are incompatible at index " + i);
        }

        /// <summary>
        /// The end that holds the list.  I.e. this is the "parent" end.
        /// </summary>
        public readonly PropertyInfo ListEnd;

        /// <summary>
        /// Properties that make up the key of the object that holds the list. Typically corresponds to primary key in classes mapped to Database.
        /// </summary>
        public readonly ReadOnlyCollection<PropertyInfo> KeyAtListEnd;

        /// <summary>
        /// The end that holds just a reference back to a single object.  I.e. this is the "child" end.
        /// </summary>
        public readonly PropertyInfo RefEnd;

        /// <summary>
        /// Properties that make up the "foreign key" that his held in the object that holds the reference.
        /// E.g. CustomerID in an Order object.
        /// </summary>
        public readonly ReadOnlyCollection<PropertyInfo> KeyAtRefEnd;

    }
}
